package org.example.classtopia.Service.Impl;

import org.example.classtopia.Mapper.AiChatMapper;
import org.example.classtopia.Model.Entity.AiChatMessage;
import org.example.classtopia.Model.Entity.AiChatSession;
import org.example.classtopia.Model.dto.AiSessionCreateDTO;
import org.example.classtopia.Model.vo.AiMessageHistoryVO;
import org.example.classtopia.Model.vo.AiMessageVO;
import org.example.classtopia.Model.vo.AiSessionListVO;
import org.example.classtopia.Model.vo.AiSessionVO;
import org.example.classtopia.Service.AiChatSessionHistoryService;
import org.example.classtopia.Common.Result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import org.example.classtopia.Utils.ThreadLocalUtil;

@Slf4j
@Service
public class AiChatSessionHistoryServiceImpl implements AiChatSessionHistoryService {

    @Autowired
    private AiChatMapper sessionMapper;

    @Autowired(required = false)
    private ChatClient chatClient;

    @Autowired(required = false)
    private ChatMemory chatMemory;

    @Autowired(required = false)
    private org.springframework.ai.openai.OpenAiChatModel directChatModel;

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    @Transactional
    public Result<AiSessionVO> createSession(AiSessionCreateDTO dto, Long ignore) {
        // 允许 userId 为空，支持匿名会话
        if (dto == null || dto.getTitle() == null || dto.getTitle().trim().isEmpty()) {
            log.error("创建会话失败：标题不能为空");
            return Result.error("会话标题不能为空");
        }
        try {
            AiChatSession session = new AiChatSession();
            session.setId(UUID.randomUUID().toString());
            session.setTitle(dto.getTitle().trim());
            // 关键：类型转换，兼容 Integer/Long
            session.setUserId(dto.getUserId() == null ? null : dto.getUserId().longValue());
            session.setCreatedAt(LocalDateTime.now());
            session.setUpdatedAt(LocalDateTime.now());
            log.info("准备为用户 {} 创建会话: {}", dto.getUserId(), session);
            int inserted = sessionMapper.insert(session);
            log.info("数据库插入结果: {}", inserted);
            if (inserted > 0) {
                AiSessionVO vo = new AiSessionVO();
                vo.setId(session.getId());
                vo.setTitle(session.getTitle());
                vo.setCreatedAt(session.getCreatedAt().format(FORMATTER));
                vo.setUpdatedAt(session.getUpdatedAt().format(FORMATTER));
                vo.setUserId(session.getUserId() != null ? session.getUserId().intValue() : null); // 关键：返回 userId
                return Result.success(vo);
            } else {
                return Result.error("创建会话失败");
            }
        } catch (Exception e) {
            log.error("创建会话异常", e);
            return Result.error("创建会话异常：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result<AiChatSession> createOrUpdateSession(String sessionId, Long userId, String title) {
        AiChatSession session = sessionMapper.selectById(sessionId);
        if (session == null) {
            session = new AiChatSession();
            session.setId(sessionId);
            session.setUserId(userId);
            session.setTitle(title);
            session.setCreatedAt(LocalDateTime.now());
            session.setUpdatedAt(LocalDateTime.now());
            sessionMapper.insert(session);
        } else {
            session.setTitle(title);
            session.setUpdatedAt(LocalDateTime.now());
            sessionMapper.update(session);
        }
        return Result.success(session);
    }

    @Override
    public Result<AiSessionListVO> getSessionList(Long userId, Integer page, Integer size) {
        try {
            // 如果没有传入用户ID，从ThreadLocal获取
            if (userId == null) {
                userId = ThreadLocalUtil.get();
                if (userId == null) {
                    log.error("获取会话列表失败：无法获取用户ID。");
                    return Result.error("用户未登录，无法获取会话列表");
                }
            }

            // 参数验证
            if (page == null || page < 1)
                page = 1;
            if (size == null || size < 1)
                size = 20;

            int offset = (page - 1) * size;
            log.info("查询用户 {} 的会话列表，offset: {}, limit: {}", userId, offset, size);

            List<AiChatSession> sessions = sessionMapper.selectSessions(userId, offset, size);
            log.info("查询到 {} 个会话", sessions.size());

            List<AiSessionVO> voList = sessions.stream().map(this::convertToSessionVO).collect(Collectors.toList());

            AiSessionListVO result = new AiSessionListVO();
            result.setSessions(voList);
            result.setTotal((long) voList.size()); // 暂时使用当前页的数量，实际应该查询总数

            return Result.success(result);
        } catch (Exception e) {
            log.error("获取会话列表时发生异常", e);
            return Result.error("获取会话列表失败：" + e.getMessage());
        }
    }

    @Override
    public Result<AiChatSession> getSessionDetail(String sessionId) {
        AiChatSession session = sessionMapper.selectById(sessionId);
        if (session == null) {
            return Result.error("会话不存在");
        }
        return Result.success(session);
    }

    @Override
    @Transactional
    public Result<Void> updateSessionTitle(String sessionId, String title) {
        AiChatSession session = sessionMapper.selectById(sessionId);
        if (session == null) {
            return Result.error("会话不存在");
        }
        session.setTitle(title);
        session.setUpdatedAt(LocalDateTime.now());
        sessionMapper.update(session);
        return Result.success();
    }

    @Override
    @Transactional
    public Result<Void> updateSessionLastActivity(String sessionId) {
        AiChatSession session = sessionMapper.selectById(sessionId);
        if (session == null) {
            return Result.error("会话不存在");
        }
        session.setUpdatedAt(LocalDateTime.now());
        sessionMapper.update(session);
        return Result.success();
    }

    @Override
    @Transactional
    public Result<Void> deleteSession(String sessionId) {
        // 增加一步：先删除关联的消息
        sessionMapper.deleteMessagesBySessionId(sessionId);
        int deleted = sessionMapper.deleteById(sessionId);
        if (deleted > 0) {
            return Result.success();
        } else {
            return Result.error("会话不存在");
        }
    }

    @Override
    public Result<AiMessageHistoryVO> getSessionMessages(String sessionId, Long userId, Integer page, Integer size) {
        log.info("获取会话消息历史，会话ID: {}", sessionId);

        try {
            AiMessageHistoryVO messageHistory = new AiMessageHistoryVO();
            int offset = (page - 1) * size;
            // 1. 优先查业务表
            List<AiChatMessage> messages = sessionMapper.selectMessagesBySessionId(sessionId, offset, size);
            if (messages != null && !messages.isEmpty()) {
                List<AiMessageVO> voList = messages.stream().map(msg -> {
                    AiMessageVO vo = new AiMessageVO();
                    vo.setId(msg.getId());
                    vo.setRole(msg.getRole());
                    vo.setContent(msg.getContent());
                    vo.setTimestamp(msg.getTimestamp() != null ? msg.getTimestamp().format(FORMATTER) : null);
                    return vo;
                }).collect(Collectors.toList());
                messageHistory.setMessages(voList);
                messageHistory.setTotal((long) voList.size());
            } else if (chatMemory != null) {
                // 2. 若表无数据，再查Spring AI ChatMemory
                var chatMessages = chatMemory.get(sessionId);
                if (chatMessages != null && !chatMessages.isEmpty()) {
                    var messageVOs = chatMessages.stream()
                            .map(message -> {
                                AiMessageVO vo = new AiMessageVO();
                                vo.setId(String.valueOf(System.currentTimeMillis() + Math.random()));
                                vo.setRole(message.getMessageType().getValue().toLowerCase());
                                vo.setContent(message.getText());
                                vo.setTimestamp(LocalDateTime.now().format(FORMATTER));
                                return vo;
                            })
                            .collect(Collectors.toList());
                    messageHistory.setMessages(messageVOs);
                    messageHistory.setTotal((long) messageVOs.size());
                } else {
                    messageHistory.setMessages(List.of());
                    messageHistory.setTotal(0L);
                }
            } else {
                messageHistory.setMessages(List.of());
                messageHistory.setTotal(0L);
            }
            return Result.success(messageHistory);
        } catch (Exception e) {
            log.error("获取会话消息历史失败: {}", e.getMessage(), e);
            return Result.error("获取消息历史失败");
        }
    }

    private AiSessionVO convertToSessionVO(AiChatSession session) {
        AiSessionVO vo = new AiSessionVO();
        vo.setId(session.getId());
        vo.setTitle(session.getTitle());
        vo.setCreatedAt(session.getCreatedAt() != null ? session.getCreatedAt().format(FORMATTER) : null);
        vo.setUpdatedAt(session.getUpdatedAt() != null ? session.getUpdatedAt().format(FORMATTER) : null);
        vo.setUserId(session.getUserId() != null ? session.getUserId().intValue() : null); // 补充 userId
        return vo;
    }

    /**
     * 处理聊天请求，保存用户消息，生成并保存AI回复，最后返回AI回复
     *
     * @param prompt      用户输入
     * @param sessionId   会话ID
     * @param currentUser 当前用户
     * @return AI的回复消息
     */
    @Transactional
    public Result<AiMessageVO> getChatResponse(String prompt, String sessionId,
            org.example.classtopia.Model.Entity.User currentUser) {
        try {
            // 1. 创建并保存用户消息
            AiChatMessage userMessage = new AiChatMessage();
            userMessage.setId(UUID.randomUUID().toString());
            userMessage.setSessionId(sessionId);
            userMessage.setRole("user");
            userMessage.setContent(prompt);
            userMessage.setTimestamp(LocalDateTime.now());
            if (currentUser != null) {
                userMessage.setUserId(currentUser.getId());
                userMessage.setUsername(currentUser.getNickname());
                userMessage.setAvatar(currentUser.getAvatar());
            } else {
                userMessage.setUserId(null); // 匿名消息
            }
            sessionMapper.insertMessage(userMessage);

            // 2. 生成AI回复（使用ChatClient和ChatMemory）
            String aiReplyContent;
            log.info("ChatClient状态: {}", chatClient != null ? "已注入" : "未注入(null)");
            log.info("ChatMemory状态: {}", chatMemory != null ? "已注入" : "未注入(null)");

            try {
                if (chatClient != null) {
                    // 使用ChatClient进行调用，自动处理记忆
                    log.info("开始调用AI ChatClient，会话ID: {}, 用户消息: {}", sessionId, prompt);

                    // 详细记录调用过程
                    log.info("准备构建ChatClient调用链...");

                    var promptBuilder = chatClient.prompt().user(prompt);
                    log.info("用户消息已设置");

                    var advisorBuilder = promptBuilder.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, sessionId));
                    log.info("ChatMemory会话ID已设置: {}", sessionId);

                    log.info("开始执行AI调用...");
                    var response = advisorBuilder.call();
                    log.info("AI调用完成，开始提取内容...");

                    aiReplyContent = response.content();
                    log.info("AI ChatClient调用成功，回复长度: {}", aiReplyContent != null ? aiReplyContent.length() : 0);
                    log.info("AI回复内容: {}", aiReplyContent);

                    // 验证回复内容
                    if (aiReplyContent == null || aiReplyContent.trim().isEmpty()) {
                        log.warn("AI回复内容为空，使用默认回复");
                        aiReplyContent = generateFallbackReply(prompt);
                    }
                } else {
                    // 降级处理：如果AI服务不可用，使用默认回复
                    aiReplyContent = generateFallbackReply(prompt);
                    log.warn("ChatClient为null，使用默认回复，会话ID: {}", sessionId);
                }
            } catch (Exception e) {
                log.error("调用AI失败，异常类型: {}", e.getClass().getSimpleName());
                log.error("调用AI失败，异常消息: {}", e.getMessage());
                log.error("调用AI失败，完整异常堆栈: ", e);

                // 尝试降级到直接ChatModel调用（绕过ChatMemory）
                aiReplyContent = tryDirectChatModelCall(prompt);
                if (aiReplyContent == null) {
                    aiReplyContent = generateFallbackReply(prompt);
                    log.warn("ChatModel降级调用也失败，已使用默认回复作为最终降级处理");
                } else {
                    log.info("ChatModel降级调用成功，回复长度: {}", aiReplyContent.length());
                }
            }

            // 3. 创建并保存AI回复消息
            AiChatMessage aiMessage = new AiChatMessage();
            aiMessage.setId(UUID.randomUUID().toString());
            aiMessage.setSessionId(sessionId);
            aiMessage.setRole("assistant");
            aiMessage.setContent(aiReplyContent);
            // 关键：AI回复时间戳比用户消息晚1秒，避免排序错乱
            aiMessage.setTimestamp(userMessage.getTimestamp().plusSeconds(1));
            if (currentUser != null) {
                aiMessage.setUserId(currentUser.getId());
                aiMessage.setUsername(currentUser.getNickname());
                aiMessage.setAvatar(currentUser.getAvatar());
            } else {
                aiMessage.setUserId(null);
            }
            sessionMapper.insertMessage(aiMessage);

            // 4. 更新会话的最后活动时间
            sessionMapper.updateLastActivity(sessionId, LocalDateTime.now());

            // 5. 将AI消息转换为VO并返回
            AiMessageVO aiMessageVO = new AiMessageVO();
            aiMessageVO.setId(aiMessage.getId());
            aiMessageVO.setRole(aiMessage.getRole());
            aiMessageVO.setContent(aiMessage.getContent());
            aiMessageVO.setTimestamp(aiMessage.getTimestamp().format(FORMATTER));

            return Result.success(aiMessageVO);
        } catch (Exception e) {
            log.error("处理聊天请求时发生异常, SessionId: {}", sessionId, e);
            return Result.error("发送消息失败：" + e.getMessage());
        }
    }

    @Transactional
public Result<AiMessageVO> AIgetChatResponse(String prompt, String sessionId,
        org.example.classtopia.Model.Entity.User currentUser, String userReply) {
    try {
        // 1. 统一时间戳
        LocalDateTime now = LocalDateTime.now();

        // 3. userReply存入chat-message表
        AiChatMessage userMessage = new AiChatMessage();
        userMessage.setId(UUID.randomUUID().toString());
        userMessage.setSessionId(sessionId);
        userMessage.setRole("user");
        userMessage.setContent(userReply);
        userMessage.setTimestamp(now);
        if (currentUser != null) {
            userMessage.setUserId(currentUser.getId());
            userMessage.setUsername(currentUser.getNickname());
            userMessage.setAvatar(currentUser.getAvatar());
        } else {
            userMessage.setUserId(null); // 匿名消息
        }
        sessionMapper.insertMessage(userMessage);

        // 4. 生成AI回复（与getChatResponse一致）
        String aiReplyContent;
        log.info("ChatClient状态: {}", chatClient != null ? "已注入" : "未注入(null)");
        log.info("ChatMemory状态: {}", chatMemory != null ? "已注入" : "未注入(null)");

        try {
            if (chatClient != null) {
                log.info("开始调用AI ChatClient，会话ID: {}, 用户消息: {}", sessionId, prompt);
                log.info("准备构建ChatClient调用链...");

                var promptBuilder = chatClient.prompt().user(prompt);
                log.info("用户消息已设置");

                var advisorBuilder = promptBuilder.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, sessionId));
                log.info("ChatMemory会话ID已设置: {}", sessionId);

                log.info("开始执行AI调用...");
                var response = advisorBuilder.call();
                log.info("AI调用完成，开始提取内容...");

                aiReplyContent = response.content();
                log.info("AI ChatClient调用成功，回复长度: {}", aiReplyContent != null ? aiReplyContent.length() : 0);
                log.info("AI回复内容: {}", aiReplyContent);

                if (aiReplyContent == null || aiReplyContent.trim().isEmpty()) {
                    log.warn("AI回复内容为空，使用默认回复");
                    aiReplyContent = generateFallbackReply(prompt);
                }
            } else {
                aiReplyContent = generateFallbackReply(prompt);
                log.warn("ChatClient为null，使用默认回复，会话ID: {}", sessionId);
            }
        } catch (Exception e) {
            log.error("调用AI失败，异常类型: {}", e.getClass().getSimpleName());
            log.error("调用AI失败，异常消息: {}", e.getMessage());
            log.error("调用AI失败，完整异常堆栈: ", e);

            aiReplyContent = tryDirectChatModelCall(prompt);
            if (aiReplyContent == null) {
                aiReplyContent = generateFallbackReply(prompt);
                log.warn("ChatModel降级调用也失败，已使用默认回复作为最终降级处理");
            } else {
                log.info("ChatModel降级调用成功，回复长度: {}", aiReplyContent.length());
            }
        }

        // 5. 保存AI回复
        AiChatMessage aiMessage = new AiChatMessage();
        aiMessage.setId(UUID.randomUUID().toString());
        aiMessage.setSessionId(sessionId);
        aiMessage.setRole("assistant");
        aiMessage.setContent(aiReplyContent);
        aiMessage.setTimestamp(now.plusSeconds(1)); // AI回复时间比用户消息晚1秒
        if (currentUser != null) {
            aiMessage.setUserId(currentUser.getId());
            aiMessage.setUsername(currentUser.getNickname());
            aiMessage.setAvatar(currentUser.getAvatar());
        } else {
            aiMessage.setUserId(null);
        }
        sessionMapper.insertMessage(aiMessage);

        // 6. 更新会话活跃时间
        sessionMapper.updateLastActivity(sessionId, LocalDateTime.now());

        // 7. 返回VO
        AiMessageVO aiMessageVO = new AiMessageVO();
        aiMessageVO.setId(aiMessage.getId());
        aiMessageVO.setRole(aiMessage.getRole());
        aiMessageVO.setContent(aiMessage.getContent());
        aiMessageVO.setTimestamp(aiMessage.getTimestamp().format(FORMATTER));

        return Result.success(aiMessageVO);
    } catch (Exception e) {
        log.error("AIgetChatResponse异常, SessionId: {}", sessionId, e);
        return Result.error("发送消息失败：" + e.getMessage());
    }
}

    @Override
    @Transactional
    public Result<Void> saveMessage(AiChatMessage message) {
        try {
            int result = sessionMapper.insertMessage(message);
            if (result > 0) {
                log.info("成功保存消息，消息ID: {}", message.getId());
                return Result.success();
            } else {
                log.error("保存消息失败，数据库未插入记录，消息ID: {}", message.getId());
                return Result.error("保存消息失败");
            }
        } catch (Exception e) {
            log.error("保存消息异常，消息ID: {}", message.getId(), e);
            return Result.error("保存消息异常：" + e.getMessage());
        }
    }

    private String generateFallbackReply(String userMessage) {
        if (userMessage.contains("你好") || userMessage.contains("hello")) {
            return "你好！很高兴见到你，有什么我可以帮助你的吗？";
        } else if (userMessage.contains("帮助") || userMessage.contains("help")) {
            return "我是你的AI助手，可以回答问题、提供建议或者陪你聊天。请告诉我你需要什么帮助。";
        } else {
            return "我收到了你的消息：\"" + userMessage + "\"。作为AI助手，我会尽力帮助你解决问题。请问还有什么其他需要了解的吗？";
        }
    }

    /**
     * 尝试直接调用ChatModel（绕过ChatMemory）
     */
    private String tryDirectChatModelCall(String prompt) {
        try {
            if (directChatModel != null) {
                log.info("尝试直接调用ChatModel（绕过ChatMemory）");

                org.springframework.ai.chat.messages.UserMessage userMsg = new org.springframework.ai.chat.messages.UserMessage(
                        prompt);
                org.springframework.ai.chat.prompt.Prompt chatPrompt = new org.springframework.ai.chat.prompt.Prompt(
                        userMsg);

                org.springframework.ai.chat.model.ChatResponse response = directChatModel.call(chatPrompt);
                String aiReply = response.getResult().getOutput().getText();

                log.info("直接ChatModel调用成功: {}", aiReply);
                return aiReply;
            } else {
                log.warn("directChatModel为null，无法进行降级调用");
                return null;
            }
        } catch (Exception e) {
            log.error("直接ChatModel调用也失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 清空会话消息
     */
    public Result<Void> clearSessionMessages(String sessionId) {
        log.info("清空会话消息，会话ID: {}", sessionId);

        try {
            if (chatMemory != null) {
                // 清空Spring AI ChatMemory中的消息
                chatMemory.clear(sessionId);
                log.info("成功清空会话 {} 的消息", sessionId);
                return Result.success();
            } else {
                log.warn("ChatMemory不可用，无法清空消息");
                return Result.error("ChatMemory服务不可用");
            }
        } catch (Exception e) {
            log.error("清空会话消息失败: {}", e.getMessage(), e);
            return Result.error("清空会话消息失败");
        }
    }

    /**
     * 调试方法：检查AI相关Bean的状态
     */
    public String checkAiBeanStatus() {
        StringBuilder status = new StringBuilder();
        status.append("=== AI Bean状态检查 ===\n");
        status.append("ChatClient: ").append(chatClient != null ? "已注入" : "未注入(null)").append("\n");
        status.append("ChatMemory: ").append(chatMemory != null ? "已注入" : "未注入(null)").append("\n");

        if (chatClient != null) {
            status.append("ChatClient类型: ").append(chatClient.getClass().getSimpleName()).append("\n");
        }
        if (chatMemory != null) {
            status.append("ChatMemory类型: ").append(chatMemory.getClass().getSimpleName()).append("\n");
        }

        return status.toString();
    }
}
